#ifndef PKG_H
#define PKG_H

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "lib.h"

#include "packagemanagement.h"
using namespace PackageManagement;

namespace PackageManagement
{

//////////////////////////////////////////////////////////////////////////////
/// Package
///
/// Class to deal with casino client packages

class Package
{
	public:
		Package();
		Package(const Package & Pkg);
		~Package();

		const String& getName();
		uint32 getZipSize();
		uint32 getUnZipSize();
		uint32 getLocalVersion();
		const String& getVersionStr();	// CSN-7534 
		uint32 getServerVersion();
		uint8 getNumDependency();
		pPkgDependency getDependencies();
		pPkgDependency getDependency(const String& name);
		uint32 getDependencyVersion(const String& name);
		bool8 isInstalled();
		bool8 allFilesInstalled();
		bool8 isLobby();
		const String& getDLLName();

#ifndef NORELOAD
		void reload();
#endif

		// DWD added:  we can turn the installed flag off, but we need
		//  a way to specify that the files are here, just need rsyncing...
		void setInstalled(bool8 Installed);
		bool8 needsDownload();
		bool8 needsUpdateCheck();
		void setUpdateChecked(bool8 checked);

		void setLobby(bool8 Lobby);
		void setDLLName(const String& DLLName);
		void setName(const String& Name);
		void setLocalVersion(uint32 Version);
		void setVersionStr(String Version);
		void setServerVersion(uint32 Version);
		void setZipSize(uint32 ZipSize);
		void setUnZipSize(uint32 size);
		void addDependency(PkgDependency* PkgD);

		void copy(Package& Src);		// moves all alloc'd data to this 

		void clearDepends();

	protected:
		//////////////////////////////////////////////////////////////////////////////
		/// Flags
		///
		/// 
		enum Flags 
		{ 
			PF_NONE			  =	0x00, 
			PF_INSTALLED	  =	0x01,
			PF_UPDATE_CHECKED = 0x08,
		};

		String name;
		String dllname;
		uint32 zipsize;
		uint32 localversion;
		uint32 serverversion;
		uint32 flags;
		uint32 unzipsize;
		pPkgDependency	depends;
		uint8	numDepends;

		String versionStr; // CSN-7534
//*************************************************************************
// IMPORTANT!  if adding/removing/changing, don't forget to change "copy()"
//*************************************************************************
};

class PkgDependency
{
	public:
		PkgDependency();
		PkgDependency(const String& name, uint32 reqVer);
		PkgDependency(const PkgDependency& PkgD);
		PkgDependency& operator=(const PkgDependency& PkgD);
		~PkgDependency();

		const String& getName();
		uint32 getRequiredVersion();

		void setName(const String& name);
		void setRequiredVersion(uint32 reqVer);

	protected:
		String name;
		uint32 reqVer;
};

//
// ------------ Package Dependency inlines
//

inline
PkgDependency::PkgDependency()
{
	reqVer = 0;
}

inline PkgDependency& 
PkgDependency::operator=(const PkgDependency& PkgD)
{
	setName(PkgD.name);
	setRequiredVersion(PkgD.reqVer);

	return *this;
}

inline
PkgDependency::PkgDependency(const String& name, uint32 reqVer)
{
	this->name = name;
	this->reqVer = reqVer;
}

inline
PkgDependency::PkgDependency(const PkgDependency& PkgD)
{
	operator=(PkgD);
}

inline
PkgDependency::~PkgDependency()
{
}

inline void
PkgDependency::setName(const String& name)
{
	this->name = name;
}

inline void
PkgDependency::setRequiredVersion(uint32 reqVer)
{
	this->reqVer = reqVer;
}

inline const String&
PkgDependency::getName()
{
	return name;
}

inline uint32
PkgDependency::getRequiredVersion()
{
	return reqVer;
}


//
// ------------ Package inlines
//

inline
Package::Package()
{
	zipsize = localversion = serverversion = 0;
	flags = PF_NONE;
	unzipsize = 0;
	depends = 0;
	numDepends = 0;
	unzipsize = 0;
}

inline const String& 
Package::getName()
{
	return name;
}

inline void
Package::setLocalVersion(uint32 Version)
{
	localversion = Version;
}

inline void
Package::setVersionStr(String Version)
{
	versionStr = Version;
}

inline void
Package::setServerVersion(uint32 Version)
{
	serverversion = Version;
}

inline void
Package::setZipSize(uint32 ZipSize)
{
	zipsize = ZipSize;
}

inline void
Package::setUnZipSize(uint32 size)
{
	unzipsize = size;
}

inline uint32 
Package::getZipSize()
{
	return zipsize;
}

inline uint32
Package::getUnZipSize()
{
	return unzipsize;
}

inline uint32 
Package::getLocalVersion()
{
	return localversion;
}

inline const String&
Package::getVersionStr()
{
	return versionStr;
}

inline uint32 
Package::getServerVersion()
{
	return serverversion;
}

inline bool8 
Package::isInstalled()
{
	return (bool8)((flags & PF_INSTALLED) != 0);
}

inline bool8 
Package::isLobby()
{
	return (name.caseCompare("Lobby") == 0);
}

inline const String& 
Package::getDLLName()
{
	return dllname;
}

inline bool8 
Package::needsDownload()
{
	return (!isInstalled() || getLocalVersion() < getServerVersion());
}

inline bool8 
Package::needsUpdateCheck()
{
	return (bool8)((flags & PF_UPDATE_CHECKED) == 0);
}

inline void
Package::setUpdateChecked(bool8 checked)
{
	if (checked)
	{
		flags |= PF_UPDATE_CHECKED;
	}
	else
	{
		flags &= ~PF_UPDATE_CHECKED;
	}
}

inline PkgDependency* 
Package::getDependencies()
{
	return depends;
}

inline uint8
Package::getNumDependency()
{
	return numDepends;
}

}; // namespace PackageManagement

#endif
